package com.jwater.core.serialize;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.jwater.core.manager.common.model.HostInfo;
import com.jwater.core.manager.common.model.JobInfo;
import com.jwater.core.manager.common.model.MasterInfo;
import com.jwater.core.manager.common.model.NodeInfo;
import com.jwater.core.manager.common.model.ProxyInfo;
import com.jwater.core.manager.common.model.WorkerInfo;
/**
 * @description:
 * @author: jnner
 * @createDate: 2021/2/5
 * @version: 1.0
 */
public class SerializeFactory {
	public static final short SERIALIZE_TYPE_SIMPLE = 0;
	public static final short SERIALIZE_TYPE_PROTO_STUFF = 1;
	public static final short SERIALIZE_TYPE_JDK = 2;

	public static final short DEFAULT_SERIALIZE_TYPE = SERIALIZE_TYPE_SIMPLE;

	private static Map<Short, SerializeService> serializeServiceCache = new ConcurrentHashMap<>();
	private static Map<String, Short> serializeTypeCache = new ConcurrentHashMap<>();

	static {
		registerSerialize(HostInfo.class.getName(), SERIALIZE_TYPE_PROTO_STUFF);
		registerSerialize(NodeInfo.class.getName(), SERIALIZE_TYPE_PROTO_STUFF);
		registerSerialize(MasterInfo.class.getName(), SERIALIZE_TYPE_PROTO_STUFF);
		registerSerialize(ProxyInfo.class.getName(), SERIALIZE_TYPE_PROTO_STUFF);
		registerSerialize(WorkerInfo.class.getName(), SERIALIZE_TYPE_PROTO_STUFF);
		registerSerialize(JobInfo.class.getName(), SERIALIZE_TYPE_PROTO_STUFF);
	}

	public static SerializeService getSerializeService(short serializeType) {
		SerializeService serializeService = serializeServiceCache.get(serializeType);
		if (serializeService == null) {
			if (serializeType == SERIALIZE_TYPE_SIMPLE) {
				serializeService = new SimpleSerialize();
			} else if (serializeType == SERIALIZE_TYPE_JDK) {
				serializeService = new JdkSerialize();
			} else if (serializeType == SERIALIZE_TYPE_PROTO_STUFF) {
				serializeService = new ProtoStuffSerialize();
			} else {
				throw new SerializeException("not support serializeType:" + serializeType);
			}
			serializeServiceCache.put(serializeType, serializeService);
		}
		return serializeService;
	}

	public static short getSerializeType(Object obj) {
		if (obj == null) {
			return SERIALIZE_TYPE_SIMPLE;
		}
		Short type = serializeTypeCache.get(obj.getClass().getName());
		if (type != null) {
			return type;
		}
		if (SimpleSerialize.isSimpleType(obj)) {
			return SerializeFactory.SERIALIZE_TYPE_SIMPLE;
		} else {
			return SerializeFactory.SERIALIZE_TYPE_JDK;
		}
	}

	public static short getSerializeType(Object[] argObjs) {
		if (argObjs == null || argObjs.length == 0) {
			return SERIALIZE_TYPE_SIMPLE;
		}
		Short type = null;
		for (Object obj : argObjs) {
			type = serializeTypeCache.get(obj.getClass().getName());
			if (type != null || SimpleSerialize.isSimpleType(obj)) {

			} else {
				return SerializeFactory.SERIALIZE_TYPE_JDK;
			}
		}
		if (type != null) {
			return type;
		}
		return SERIALIZE_TYPE_SIMPLE;
	}

	/**
	 * 可以自定义序列化服务，注册进来
	 * 
	 * @param serializeType
	 * @param serializeService
	 */
	public static void addSerializeService(short serializeType, SerializeService serializeService) {
		serializeServiceCache.put(serializeType, serializeService);
	}

	/**
	 * 
	 * @param className
	 * @param serializeType
	 */
	public static void registerSerialize(String className, short serializeType) {
		serializeTypeCache.put(className, serializeType);
	}
}
